﻿// ------------------------------------------------------------------------------------------------
//  <copyright file="StateQueue.cs" company="Iveely">
//    Copyright (c) Iveely Liu.  All rights reserved.
//  </copyright>
//  
//  <Create Time>
//    03/02/2013 21:59 
//  </Create Time>
//  
//  <contact owner>
//    liufanping@iveely.com 
//  </contact owner>
//  -----------------------------------------------------------------------------------------------

#region

using System;
using System.Collections.Generic;

#endregion

namespace IveelySE.NLP.Common.DataStructure
{
    /// <summary>
    ///   状态队列
    /// </summary>
    [Serializable]
    public class StateQueue
    {
        /// <summary>
        ///   存储队列
        /// </summary>
        private readonly List<Row> Queue = new List<Row>();

        public string this[int index]
        {
            get { return this.Queue[index].Key; }
        }


        /// <summary>
        ///   添加状态信息
        /// </summary>
        /// <param name="key"> 关键字 </param>
        /// <param name="state"> 关键字状态 </param>
        public void Add(string key, int state)
        {
            this.Queue.Add(new Row(key, state));
        }

        /// <summary>
        ///   添加状态信息
        /// </summary>
        /// <param name="key"> 关键字字符集合 </param>
        /// <param name="keys"> </param>
        /// <param name="state"> 默认集合中所有关键字状态 </param>
        public void Add(string[] keys, int state)
        {
            foreach(string key in keys)
            {
                this.Add(key, state);
            }
        }

        /// <summary>
        ///   修改状态信息
        /// </summary>
        /// <param name="key"> 关键字 </param>
        /// <param name="sate"> 关键字状态 </param>
        public void Update(string key, int state)
        {
            //依次便利
            for(int i = 0; i < this.Queue.Count; i++)
            {
                //如果关键字相等，且状态不想等
                if(this.Queue[i].Key.Equals(key) && !this.Queue[i].State.Equals(state))
                {
                    this.Queue[i].State = state;
                    break;
                }
            }
        }

        /// <summary>
        ///   修改状态信息
        /// </summary>
        /// <param name="key"> 需要修改的关键字集合 </param>
        /// <param name="sate"> 关键字集合统一修改状态 </param>
        public void Update(string[] keys, int state)
        {
            foreach(string key in keys)
            {
                this.Update(key, state);
            }
        }

        /// <summary>
        ///   分断技术
        /// </summary>
        /// <param name="state"> 队列分割状态符 </param>
        /// <returns> </returns>
        public List<string> Decoupling(int state)
        {
            return null;
        }

        /// <summary>
        ///   遍历状态队列
        /// </summary>
        /// <param name="keys"> 开始关键字集合 </param>
        /// <param name="state"> 开始关键字统一的状态 </param>
        /// <returns> 返回遍历后的字符串 </returns>
        public List<string> Traversal(string[] keys, int state)
        {
            var result = new List<string>();
            bool continuous = false;
            for(int i = 0; i < keys.Length; i++)
            {
                if(!continuous)
                {
                    result.AddRange(this.Traversal(state));
                }
                this.Update(keys[i], 2);
            }
            return result;
        }


        /// <summary>
        ///   根据状态遍历
        /// </summary>
        /// <param name="state"> </param>
        /// <returns> </returns>
        public List<string> Traversal(int state)
        {
            var result = new List<string>();
            var forward = new List<string>();
            var reverse = new List<string>();
            //标记前面
            if(this.Queue.Count > 0 && this.Queue[0].State == 0)
            {
                forward.Add("*");
            }

            bool flag = true;
            foreach(Row row in this.Queue)
            {
                if(flag)
                {
                    if(row.State != 0 && row.State != 2)
                    {
                        forward.Add(row.Key);
                        flag = false;
                    }
                    else
                    {
                        reverse.Add(row.Key);
                    }
                    if(!flag)
                    {
                        reverse.Add(row.Key);
                    }
                }
                else
                {
                    if(row.State != 0)
                    {
                        reverse.Add(row.Key);
                    }
                    forward.Add(row.Key);
                }
            }
            //标记后面
            if(this.Queue.Count > 0 && this.Queue[this.Queue.Count - 1].State == 0)
            {
                reverse.Add("*");
            }
            string forwardStr = string.Join("", forward.ToArray());
            string reverseStr = string.Join("", reverse.ToArray());
            if(forwardStr.Length > 3)
            {
                result.Add(forwardStr);
            }
            if(reverseStr.Length > 3)
            {
                result.Add(reverseStr);
            }
            return result;
        }

        /// <summary>
        ///   返回队列元素个数
        /// </summary>
        /// <returns> 元素个数 </returns>
        public int Count()
        {
            return this.Queue.Count;
        }

        public void Clean()
        {
            this.Queue.Clear();
        }

        #region Nested type: Row

        /// <summary>
        ///   状态行
        /// </summary>
        private class Row
        {
            /// <summary>
            ///   构造方法
            /// </summary>
            /// <param name="key"> 关键字 </param>
            /// <param name="state"> 关键字状态 </param>
            public Row(string key, int state)
            {
                this.Key = key;
                this.State = state;
            }

            /// <summary>
            ///   关键字
            /// </summary>
            public string Key { get; set; }

            /// <summary>
            ///   关键字的状态
            /// </summary>
            public int State { get; set; }
        }

        #endregion
    }
}